Load the libraries.

library(data.table)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
data.table 1.12.2 using 4 threads (see ?getDTthreads).  Latest news: r-datatable.com
library(ggplot2)

The code below will show the data cleaning and exploration.

First load the data.

Data Wrangling

setwd("C:/Users/Ferhat/Documents/GitHub/WorldBankData")
The working directory was changed to C:/Users/Ferhat/Documents/GitHub/WorldBankData inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
data = read.csv("MBSComtrade.csv")

data$series_type = NULL
data$table_type = NULL
data$table_type_desc = NULL
data$period_type = NULL
data$trade_flow = NULL
data$currency_type = NULL
data$value_unit = NULL
data$value_type = NULL
data$value_type_desc = NULL
data$base_year = NULL
data$period_number = NULL
data$country_type = NULL
data$estimation_type = NULL
data$estimation_type_desc = NULL


save(data, file = "cleaned_data.rdata")
data = as.data.table(data)

Lets explore some of the data.

head(data[country_english_name == "USA"],10)

Lets do some plots. But first lets get rid of world regions and only keep countryes so we don’t double count. Lets look at the USA first.

USA = data[country_english_name == "USA" & partner_country_code > 0 & partner_country_code < 899 ]
head(USA,10)

Now lets group everything by partner export country.

USA_group = USA[, .(value.SUM = sum(value)), by=c("partner_country_english_name", "year")]
setnames(USA_group, c("Country","Year", "TotalValue") )
head(USA_group,10)

Now lets plot.

Line chart


library(plotly)

Attaching package: 㤼㸱plotly㤼㸲

The following object is masked from 㤼㸱package:ggplot2㤼㸲:

    last_plot

The following object is masked from 㤼㸱package:stats㤼㸲:

    filter

The following object is masked from 㤼㸱package:graphics㤼㸲:

    layout
p = ggplot(USA_group, aes(x = Year, y=TotalValue))+
  geom_line(aes(colour = Country))+
  geom_point(aes(colour = Country), size=2)+
  theme(legend.position="none")

ggplotly(p)

Pie chart

rr ggplot(USA_group, aes(x=factor(1), fill = factor(Country)))+ geom_bar(aes(weight = TotalValue), width = 1)+ coord_polar(theta = , start=0)+ theme(legend.position=)

Sankey Diagram

USA_group_country = USA_group[, .(Sum = sum(TotalValue)), by=Country]
USA_group_country$Source = "USA"
USA_group_country[, Country:=as.character(Country)]

USA_group_country <- USA_group_country %>% 
  select(Country, Source, Sum)
setorder(USA_group_country, Sum)

slice = tail(USA_group_country, 10)

slice <- slice %>% 
  select(Source, Country, Sum)

library(googleVis)

Creating a generic function for 㤼㸱toJSON㤼㸲 from package 㤼㸱jsonlite㤼㸲 in package 㤼㸱googleVis㤼㸲

Welcome to googleVis version 0.6.4

Please read Google’s Terms of Use before you start using the package: https://developers.google.com/terms/

Note, the plot method of googleVis will by default use the standard browser to display its output.

See the googleVis package vignettes for more details, or visit https://github.com/mages/googleVis.

To suppress this message use: suppressPackageStartupMessages(library(googleVis))

sk1 <- gvisSankey(slice, from="Source", to="Country", weight="Sum")
print(sk1, 'chart')

Lets play with leaflet package.

Leaflet

library(leaflet)
m <- leaflet() %>% setView(lng = -71.0589, lat = 42.3601, zoom = 12)
m %>% addTiles()

Lets get the latitude and longitude of countries.

rr countries = read.csv(.csv) countries = as.data.table(countries) setnames(countries, old = c(, ), new = c(, ))

head(countries,10)

Now lets populate USA_group data table the latitude and longitude of the countries.

USA_group_joined = merge(USA_group, countries, by = "Country")

na.omit(USA_group_joined)

head(USA_group_joined, 10)
setorder(USA_group_joined, Country, Year)
leaflet(USA_group_joined[USA_group_joined[,Year == 2010]]) %>% addTiles() %>%
  addCircles(lng = ~longitude, lat = ~latitude, weight = 1,
    radius = ~sqrt(TotalValue), popup = ~paste(Country,"Volume: ",TotalValue), fillOpacity = 0.5
  )

Now lets look at the flows using Leaflet’s addflows function.


leaflet(USA_group_joined[USA_group_joined[,Year == 2010]]) %>% addTiles() %>%
  addCircles(lng = ~longitude, lat = ~latitude, weight = 1,
    radius = ~sqrt(TotalValue), popup = ~paste(Country,"Volume: ",TotalValue), fillOpacity = 0.5
  ) %>%
  leaflet.minicharts::addFlows(countries$longitude[countries$Country == "United States"], countries$latitude[countries$Country == "United States"],
           countries$longitude[countries$Country == "Brazil"], countries$latitude[countries$Country == "Brazil"], color = 'green',
           flow = USA_group_joined[USA_group_joined[,Year == 2010 & Country == "Brazil"]]$TotalValue, opacity = 0.5) %>%
  leaflet.minicharts::addFlows(countries$longitude[countries$Country == "United States"], countries$latitude[countries$Country == "United States"],
           countries$longitude[countries$Country == "China"], countries$latitude[countries$Country == "China"], color = 'red',
           flow = USA_group_joined[USA_group_joined[,Year == 2010 & Country == "China"]]$TotalValue, opacity = 0.5) %>%
  leaflet.minicharts::addFlows(countries$longitude[countries$Country == "United States"], countries$latitude[countries$Country == "United States"],
           countries$longitude[countries$Country == "Australia"], countries$latitude[countries$Country == "Australia"], color = 'orange',
           flow = USA_group_joined[USA_group_joined[,Year == 2010 & Country == "Australia"]]$TotalValue, opacity = 0.5)

NA
NA

Lets do it with time

leaflet(USA_group_joined) %>% addTiles() %>%
  leaflet.minicharts::addFlows(countries$longitude[countries$Country == "United States"], countries$latitude[countries$Country == "United States"],
           countries$longitude[countries$Country == "Brazil"], countries$latitude[countries$Country == "Brazil"], color = 'green',
           flow = USA_group_joined[USA_group_joined[, Country == "Brazil"]]$TotalValue, opacity = 0.5, time = unique(USA_group_joined$Year)) %>%
  leaflet.minicharts::addFlows(countries$longitude[countries$Country == "United States"], countries$latitude[countries$Country == "United States"],
           countries$longitude[countries$Country == "China"], countries$latitude[countries$Country == "China"], color = 'red',
           flow = USA_group_joined[USA_group_joined[, Country == "China"]]$TotalValue, opacity = 0.5, time =unique(USA_group_joined$Year)) %>%
  leaflet.minicharts::addFlows(countries$longitude[countries$Country == "United States"], countries$latitude[countries$Country == "United States"],
           countries$longitude[countries$Country == "Australia"], countries$latitude[countries$Country == "Australia"], color = 'orange',
           flow = USA_group_joined[USA_group_joined[, Country == "Australia"]]$TotalValue, opacity = 0.5, time =unique(USA_group_joined$Year)) %>%
    leaflet.minicharts::addFlows(countries$longitude[countries$Country == "United States"], countries$latitude[countries$Country == "United States"],
           countries$longitude[countries$Country == "Albania"], countries$latitude[countries$Country == "Albania"], color = 'black',
           flow = USA_group_joined[USA_group_joined[, Country == "Albania"]]$TotalValue, opacity = 0.5, time =unique(USA_group_joined$Year))

basemap = leaflet(USA_group_joined) %>% addTiles()

basemap %>% leaflet.minicharts::addFlows(countries$longitude[countries$Country == "United States"], countries$latitude[countries$Country == "United States"],USA_group_joined$longitude, USA_group_joined$latitude,
    flow = USA_group_joined$TotalValue,
    time = USA_group_joined$Year)

USA Group Joined cut to show select countries.

USA_group_joined_cut = USA_group_joined[Country %in% c("Canada", "China", "Brazil", "India", "Australia", "South Africa", "Mexico")]

Repeat the plot

basemap = leaflet(USA_group_joined_cut) %>% addTiles()

basemap %>% leaflet.minicharts::addFlows(countries$longitude[countries$Country == "United States"], countries$latitude[countries$Country == "United States"],USA_group_joined_cut$longitude, USA_group_joined_cut$latitude,
    flow = USA_group_joined_cut$TotalValue,
    time = USA_group_joined_cut$Year)
LS0tDQp0aXRsZTogIk1CUyBDb210cmFkZSBEYXRhIE5vdGVib29rIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KDQpMb2FkIHRoZSBsaWJyYXJpZXMuDQoNCmBgYHtyfQ0KbGlicmFyeShkYXRhLnRhYmxlKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KYGBgDQoNClRoZSBjb2RlIGJlbG93IHdpbGwgc2hvdyB0aGUgZGF0YSBjbGVhbmluZyBhbmQgZXhwbG9yYXRpb24uDQoNCkZpcnN0IGxvYWQgdGhlIGRhdGEuDQoNCiMgRGF0YSBXcmFuZ2xpbmcNCg0KYGBge3J9DQpzZXR3ZCgiQzovVXNlcnMvRmVyaGF0L0RvY3VtZW50cy9HaXRIdWIvV29ybGRCYW5rRGF0YSIpDQoNCmRhdGEgPSByZWFkLmNzdigiTUJTQ29tdHJhZGUuY3N2IikNCg0KZGF0YSRzZXJpZXNfdHlwZSA9IE5VTEwNCmRhdGEkdGFibGVfdHlwZSA9IE5VTEwNCmRhdGEkdGFibGVfdHlwZV9kZXNjID0gTlVMTA0KZGF0YSRwZXJpb2RfdHlwZSA9IE5VTEwNCmRhdGEkdHJhZGVfZmxvdyA9IE5VTEwNCmRhdGEkY3VycmVuY3lfdHlwZSA9IE5VTEwNCmRhdGEkdmFsdWVfdW5pdCA9IE5VTEwNCmRhdGEkdmFsdWVfdHlwZSA9IE5VTEwNCmRhdGEkdmFsdWVfdHlwZV9kZXNjID0gTlVMTA0KZGF0YSRiYXNlX3llYXIgPSBOVUxMDQpkYXRhJHBlcmlvZF9udW1iZXIgPSBOVUxMDQpkYXRhJGNvdW50cnlfdHlwZSA9IE5VTEwNCmRhdGEkZXN0aW1hdGlvbl90eXBlID0gTlVMTA0KZGF0YSRlc3RpbWF0aW9uX3R5cGVfZGVzYyA9IE5VTEwNCg0KDQpzYXZlKGRhdGEsIGZpbGUgPSAiY2xlYW5lZF9kYXRhLnJkYXRhIikNCmBgYA0KDQpgYGB7cn0NCmRhdGEgPSBhcy5kYXRhLnRhYmxlKGRhdGEpDQpgYGANCg0KTGV0cyBleHBsb3JlIHNvbWUgb2YgdGhlIGRhdGEuDQoNCmBgYHtyfQ0KaGVhZChkYXRhW2NvdW50cnlfZW5nbGlzaF9uYW1lID09ICJVU0EiXSwxMCkNCmBgYA0KTGV0cyBkbyBzb21lIHBsb3RzLiBCdXQgZmlyc3QgbGV0cyBnZXQgcmlkIG9mIHdvcmxkIHJlZ2lvbnMgYW5kIG9ubHkga2VlcCBjb3VudHJ5ZXMgc28gd2UgZG9uJ3QgZG91YmxlIGNvdW50LiBMZXRzIGxvb2sgYXQgdGhlIFVTQSBmaXJzdC4NCmBgYHtyfQ0KVVNBID0gZGF0YVtjb3VudHJ5X2VuZ2xpc2hfbmFtZSA9PSAiVVNBIiAmIHBhcnRuZXJfY291bnRyeV9jb2RlID4gMCAmIHBhcnRuZXJfY291bnRyeV9jb2RlIDwgODk5IF0NCmhlYWQoVVNBLDEwKQ0KYGBgDQoNCk5vdyBsZXRzIGdyb3VwICBldmVyeXRoaW5nIGJ5IHBhcnRuZXIgZXhwb3J0IGNvdW50cnkuDQpgYGB7cn0NClVTQV9ncm91cCA9IFVTQVssIC4odmFsdWUuU1VNID0gc3VtKHZhbHVlKSksIGJ5PWMoInBhcnRuZXJfY291bnRyeV9lbmdsaXNoX25hbWUiLCAieWVhciIpXQ0Kc2V0bmFtZXMoVVNBX2dyb3VwLCBjKCJDb3VudHJ5IiwiWWVhciIsICJUb3RhbFZhbHVlIikgKQ0KaGVhZChVU0FfZ3JvdXAsMTApDQpgYGANCg0KTm93IGxldHMgcGxvdC4NCg0KIyBMaW5lIGNoYXJ0DQoNCmBgYHtyfQ0KDQpsaWJyYXJ5KHBsb3RseSkNCnAgPSBnZ3Bsb3QoVVNBX2dyb3VwLCBhZXMoeCA9IFllYXIsIHk9VG90YWxWYWx1ZSkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IENvdW50cnkpKSsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gQ291bnRyeSksIHNpemU9MikrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpDQoNCmdncGxvdGx5KHApDQpgYGANCiMgUGllIGNoYXJ0DQoNCmBgYHtyfQ0KZ2dwbG90KFVTQV9ncm91cCwgYWVzKHg9ZmFjdG9yKDEpLCBmaWxsID0gZmFjdG9yKENvdW50cnkpKSkrDQogIGdlb21fYmFyKGFlcyh3ZWlnaHQgPSBUb3RhbFZhbHVlKSwgd2lkdGggPSAxKSsNCiAgY29vcmRfcG9sYXIodGhldGEgPSAieSIsIHN0YXJ0PTApKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQ0KYGBgDQoNCiMgU2Fua2V5IERpYWdyYW0NCg0KYGBge3IgIHJlc3VsdHM9J2FzaXMnfQ0KVVNBX2dyb3VwX2NvdW50cnkgPSBVU0FfZ3JvdXBbLCAuKFN1bSA9IHN1bShUb3RhbFZhbHVlKSksIGJ5PUNvdW50cnldDQpVU0FfZ3JvdXBfY291bnRyeSRTb3VyY2UgPSAiVVNBIg0KVVNBX2dyb3VwX2NvdW50cnlbLCBDb3VudHJ5Oj1hcy5jaGFyYWN0ZXIoQ291bnRyeSldDQoNClVTQV9ncm91cF9jb3VudHJ5IDwtIFVTQV9ncm91cF9jb3VudHJ5ICU+JSANCiAgc2VsZWN0KENvdW50cnksIFNvdXJjZSwgU3VtKQ0Kc2V0b3JkZXIoVVNBX2dyb3VwX2NvdW50cnksIFN1bSkNCg0Kc2xpY2UgPSB0YWlsKFVTQV9ncm91cF9jb3VudHJ5LCAxMCkNCg0Kc2xpY2UgPC0gc2xpY2UgJT4lIA0KICBzZWxlY3QoU291cmNlLCBDb3VudHJ5LCBTdW0pDQoNCmxpYnJhcnkoZ29vZ2xlVmlzKQ0Kc2sxIDwtIGd2aXNTYW5rZXkoc2xpY2UsIGZyb209IlNvdXJjZSIsIHRvPSJDb3VudHJ5Iiwgd2VpZ2h0PSJTdW0iKQ0KcHJpbnQoc2sxLCAnY2hhcnQnKQ0KYGBgDQpMZXRzIHBsYXkgd2l0aCBsZWFmbGV0IHBhY2thZ2UuDQoNCiMgTGVhZmxldA0KDQpgYGB7cn0NCmxpYnJhcnkobGVhZmxldCkNCm0gPC0gbGVhZmxldCgpICU+JSBzZXRWaWV3KGxuZyA9IC03MS4wNTg5LCBsYXQgPSA0Mi4zNjAxLCB6b29tID0gMTIpDQptICU+JSBhZGRUaWxlcygpDQpgYGANCkxldHMgZ2V0IHRoZSBsYXRpdHVkZSBhbmQgbG9uZ2l0dWRlIG9mIGNvdW50cmllcy4NCg0KYGBge3J9DQpjb3VudHJpZXMgPSByZWFkLmNzdigiY291bnRyaWVzLmNzdiIpDQpjb3VudHJpZXMgPSBhcy5kYXRhLnRhYmxlKGNvdW50cmllcykNCnNldG5hbWVzKGNvdW50cmllcywgb2xkID0gYygiY291bnRyeSIsICJuYW1lIiksIG5ldyA9IGMoIkNvdW50cnlDb2RlIiwgIkNvdW50cnkiKSkNCg0KaGVhZChjb3VudHJpZXMsMTApDQpgYGANCk5vdyBsZXRzIHBvcHVsYXRlIFVTQV9ncm91cCBkYXRhIHRhYmxlIHRoZSBsYXRpdHVkZSBhbmQgbG9uZ2l0dWRlIG9mIHRoZSBjb3VudHJpZXMuDQoNCmBgYHtyfQ0KVVNBX2dyb3VwX2pvaW5lZCA9IG1lcmdlKFVTQV9ncm91cCwgY291bnRyaWVzLCBieSA9ICJDb3VudHJ5IikNCg0KbmEub21pdChVU0FfZ3JvdXBfam9pbmVkKQ0KDQpoZWFkKFVTQV9ncm91cF9qb2luZWQsIDEwKQ0KYGBgDQoNCmBgYHtyfQ0Kc2V0b3JkZXIoVVNBX2dyb3VwX2pvaW5lZCwgQ291bnRyeSwgWWVhcikNCmxlYWZsZXQoVVNBX2dyb3VwX2pvaW5lZFtVU0FfZ3JvdXBfam9pbmVkWyxZZWFyID09IDIwMTBdXSkgJT4lIGFkZFRpbGVzKCkgJT4lDQogIGFkZENpcmNsZXMobG5nID0gfmxvbmdpdHVkZSwgbGF0ID0gfmxhdGl0dWRlLCB3ZWlnaHQgPSAxLA0KICAgIHJhZGl1cyA9IH5zcXJ0KFRvdGFsVmFsdWUpLCBwb3B1cCA9IH5wYXN0ZShDb3VudHJ5LCJWb2x1bWU6ICIsVG90YWxWYWx1ZSksIGZpbGxPcGFjaXR5ID0gMC41DQogICkNCmBgYA0KDQpOb3cgbGV0cyBsb29rIGF0IHRoZSBmbG93cyB1c2luZyBMZWFmbGV0J3MgYWRkZmxvd3MgZnVuY3Rpb24uDQoNCmBgYHtyfQ0KDQpsZWFmbGV0KFVTQV9ncm91cF9qb2luZWRbVVNBX2dyb3VwX2pvaW5lZFssWWVhciA9PSAyMDEwXV0pICU+JSBhZGRUaWxlcygpICU+JQ0KICBhZGRDaXJjbGVzKGxuZyA9IH5sb25naXR1ZGUsIGxhdCA9IH5sYXRpdHVkZSwgd2VpZ2h0ID0gMSwNCiAgICByYWRpdXMgPSB+c3FydChUb3RhbFZhbHVlKSwgcG9wdXAgPSB+cGFzdGUoQ291bnRyeSwiVm9sdW1lOiAiLFRvdGFsVmFsdWUpLCBmaWxsT3BhY2l0eSA9IDAuNQ0KICApICU+JQ0KICBsZWFmbGV0Lm1pbmljaGFydHM6OmFkZEZsb3dzKGNvdW50cmllcyRsb25naXR1ZGVbY291bnRyaWVzJENvdW50cnkgPT0gIlVuaXRlZCBTdGF0ZXMiXSwgY291bnRyaWVzJGxhdGl0dWRlW2NvdW50cmllcyRDb3VudHJ5ID09ICJVbml0ZWQgU3RhdGVzIl0sDQogICAgICAgICAgIGNvdW50cmllcyRsb25naXR1ZGVbY291bnRyaWVzJENvdW50cnkgPT0gIkJyYXppbCJdLCBjb3VudHJpZXMkbGF0aXR1ZGVbY291bnRyaWVzJENvdW50cnkgPT0gIkJyYXppbCJdLCBjb2xvciA9ICdncmVlbicsDQogICAgICAgICAgIGZsb3cgPSBVU0FfZ3JvdXBfam9pbmVkW1VTQV9ncm91cF9qb2luZWRbLFllYXIgPT0gMjAxMCAmIENvdW50cnkgPT0gIkJyYXppbCJdXSRUb3RhbFZhbHVlLCBvcGFjaXR5ID0gMC41KSAlPiUNCiAgbGVhZmxldC5taW5pY2hhcnRzOjphZGRGbG93cyhjb3VudHJpZXMkbG9uZ2l0dWRlW2NvdW50cmllcyRDb3VudHJ5ID09ICJVbml0ZWQgU3RhdGVzIl0sIGNvdW50cmllcyRsYXRpdHVkZVtjb3VudHJpZXMkQ291bnRyeSA9PSAiVW5pdGVkIFN0YXRlcyJdLA0KICAgICAgICAgICBjb3VudHJpZXMkbG9uZ2l0dWRlW2NvdW50cmllcyRDb3VudHJ5ID09ICJDaGluYSJdLCBjb3VudHJpZXMkbGF0aXR1ZGVbY291bnRyaWVzJENvdW50cnkgPT0gIkNoaW5hIl0sIGNvbG9yID0gJ3JlZCcsDQogICAgICAgICAgIGZsb3cgPSBVU0FfZ3JvdXBfam9pbmVkW1VTQV9ncm91cF9qb2luZWRbLFllYXIgPT0gMjAxMCAmIENvdW50cnkgPT0gIkNoaW5hIl1dJFRvdGFsVmFsdWUsIG9wYWNpdHkgPSAwLjUpICU+JQ0KICBsZWFmbGV0Lm1pbmljaGFydHM6OmFkZEZsb3dzKGNvdW50cmllcyRsb25naXR1ZGVbY291bnRyaWVzJENvdW50cnkgPT0gIlVuaXRlZCBTdGF0ZXMiXSwgY291bnRyaWVzJGxhdGl0dWRlW2NvdW50cmllcyRDb3VudHJ5ID09ICJVbml0ZWQgU3RhdGVzIl0sDQogICAgICAgICAgIGNvdW50cmllcyRsb25naXR1ZGVbY291bnRyaWVzJENvdW50cnkgPT0gIkF1c3RyYWxpYSJdLCBjb3VudHJpZXMkbGF0aXR1ZGVbY291bnRyaWVzJENvdW50cnkgPT0gIkF1c3RyYWxpYSJdLCBjb2xvciA9ICdvcmFuZ2UnLA0KICAgICAgICAgICBmbG93ID0gVVNBX2dyb3VwX2pvaW5lZFtVU0FfZ3JvdXBfam9pbmVkWyxZZWFyID09IDIwMTAgJiBDb3VudHJ5ID09ICJBdXN0cmFsaWEiXV0kVG90YWxWYWx1ZSwgb3BhY2l0eSA9IDAuNSkNCg0KDQpgYGANCg0KTGV0cyBkbyBpdCB3aXRoIHRpbWUNCg0KYGBge3J9DQpsZWFmbGV0KFVTQV9ncm91cF9qb2luZWQpICU+JSBhZGRUaWxlcygpICU+JQ0KICBsZWFmbGV0Lm1pbmljaGFydHM6OmFkZEZsb3dzKGNvdW50cmllcyRsb25naXR1ZGVbY291bnRyaWVzJENvdW50cnkgPT0gIlVuaXRlZCBTdGF0ZXMiXSwgY291bnRyaWVzJGxhdGl0dWRlW2NvdW50cmllcyRDb3VudHJ5ID09ICJVbml0ZWQgU3RhdGVzIl0sDQogICAgICAgICAgIGNvdW50cmllcyRsb25naXR1ZGVbY291bnRyaWVzJENvdW50cnkgPT0gIkJyYXppbCJdLCBjb3VudHJpZXMkbGF0aXR1ZGVbY291bnRyaWVzJENvdW50cnkgPT0gIkJyYXppbCJdLCBjb2xvciA9ICdncmVlbicsDQogICAgICAgICAgIGZsb3cgPSBVU0FfZ3JvdXBfam9pbmVkW1VTQV9ncm91cF9qb2luZWRbLCBDb3VudHJ5ID09ICJCcmF6aWwiXV0kVG90YWxWYWx1ZSwgb3BhY2l0eSA9IDAuNSwgdGltZSA9IHVuaXF1ZShVU0FfZ3JvdXBfam9pbmVkJFllYXIpKSAlPiUNCiAgbGVhZmxldC5taW5pY2hhcnRzOjphZGRGbG93cyhjb3VudHJpZXMkbG9uZ2l0dWRlW2NvdW50cmllcyRDb3VudHJ5ID09ICJVbml0ZWQgU3RhdGVzIl0sIGNvdW50cmllcyRsYXRpdHVkZVtjb3VudHJpZXMkQ291bnRyeSA9PSAiVW5pdGVkIFN0YXRlcyJdLA0KICAgICAgICAgICBjb3VudHJpZXMkbG9uZ2l0dWRlW2NvdW50cmllcyRDb3VudHJ5ID09ICJDaGluYSJdLCBjb3VudHJpZXMkbGF0aXR1ZGVbY291bnRyaWVzJENvdW50cnkgPT0gIkNoaW5hIl0sIGNvbG9yID0gJ3JlZCcsDQogICAgICAgICAgIGZsb3cgPSBVU0FfZ3JvdXBfam9pbmVkW1VTQV9ncm91cF9qb2luZWRbLCBDb3VudHJ5ID09ICJDaGluYSJdXSRUb3RhbFZhbHVlLCBvcGFjaXR5ID0gMC41LCB0aW1lID11bmlxdWUoVVNBX2dyb3VwX2pvaW5lZCRZZWFyKSkgJT4lDQogIGxlYWZsZXQubWluaWNoYXJ0czo6YWRkRmxvd3MoY291bnRyaWVzJGxvbmdpdHVkZVtjb3VudHJpZXMkQ291bnRyeSA9PSAiVW5pdGVkIFN0YXRlcyJdLCBjb3VudHJpZXMkbGF0aXR1ZGVbY291bnRyaWVzJENvdW50cnkgPT0gIlVuaXRlZCBTdGF0ZXMiXSwNCiAgICAgICAgICAgY291bnRyaWVzJGxvbmdpdHVkZVtjb3VudHJpZXMkQ291bnRyeSA9PSAiQXVzdHJhbGlhIl0sIGNvdW50cmllcyRsYXRpdHVkZVtjb3VudHJpZXMkQ291bnRyeSA9PSAiQXVzdHJhbGlhIl0sIGNvbG9yID0gJ29yYW5nZScsDQogICAgICAgICAgIGZsb3cgPSBVU0FfZ3JvdXBfam9pbmVkW1VTQV9ncm91cF9qb2luZWRbLCBDb3VudHJ5ID09ICJBdXN0cmFsaWEiXV0kVG90YWxWYWx1ZSwgb3BhY2l0eSA9IDAuNSwgdGltZSA9dW5pcXVlKFVTQV9ncm91cF9qb2luZWQkWWVhcikpICU+JQ0KICAgIGxlYWZsZXQubWluaWNoYXJ0czo6YWRkRmxvd3MoY291bnRyaWVzJGxvbmdpdHVkZVtjb3VudHJpZXMkQ291bnRyeSA9PSAiVW5pdGVkIFN0YXRlcyJdLCBjb3VudHJpZXMkbGF0aXR1ZGVbY291bnRyaWVzJENvdW50cnkgPT0gIlVuaXRlZCBTdGF0ZXMiXSwNCiAgICAgICAgICAgY291bnRyaWVzJGxvbmdpdHVkZVtjb3VudHJpZXMkQ291bnRyeSA9PSAiQWxiYW5pYSJdLCBjb3VudHJpZXMkbGF0aXR1ZGVbY291bnRyaWVzJENvdW50cnkgPT0gIkFsYmFuaWEiXSwgY29sb3IgPSAnYmxhY2snLA0KICAgICAgICAgICBmbG93ID0gVVNBX2dyb3VwX2pvaW5lZFtVU0FfZ3JvdXBfam9pbmVkWywgQ291bnRyeSA9PSAiQWxiYW5pYSJdXSRUb3RhbFZhbHVlLCBvcGFjaXR5ID0gMC41LCB0aW1lID11bmlxdWUoVVNBX2dyb3VwX2pvaW5lZCRZZWFyKSkNCmBgYA0KDQoNCmBgYHtyfQ0KDQpiYXNlbWFwID0gbGVhZmxldChVU0FfZ3JvdXBfam9pbmVkKSAlPiUgYWRkVGlsZXMoKQ0KDQpiYXNlbWFwICU+JSBsZWFmbGV0Lm1pbmljaGFydHM6OmFkZEZsb3dzKGNvdW50cmllcyRsb25naXR1ZGVbY291bnRyaWVzJENvdW50cnkgPT0gIlVuaXRlZCBTdGF0ZXMiXSwgY291bnRyaWVzJGxhdGl0dWRlW2NvdW50cmllcyRDb3VudHJ5ID09ICJVbml0ZWQgU3RhdGVzIl0sVVNBX2dyb3VwX2pvaW5lZCRsb25naXR1ZGUsIFVTQV9ncm91cF9qb2luZWQkbGF0aXR1ZGUsDQogICAgZmxvdyA9IFVTQV9ncm91cF9qb2luZWQkVG90YWxWYWx1ZSwNCiAgICB0aW1lID0gVVNBX2dyb3VwX2pvaW5lZCRZZWFyKQ0KYGBgDQoNClVTQSBHcm91cCBKb2luZWQgY3V0IHRvIHNob3cgc2VsZWN0IGNvdW50cmllcy4NCg0KYGBge3J9DQpVU0FfZ3JvdXBfam9pbmVkX2N1dCA9IFVTQV9ncm91cF9qb2luZWRbQ291bnRyeSAlaW4lIGMoIkNhbmFkYSIsICJDaGluYSIsICJCcmF6aWwiLCAiSW5kaWEiLCAiQXVzdHJhbGlhIiwgIlNvdXRoIEFmcmljYSIsICJNZXhpY28iKV0NCmBgYA0KDQpSZXBlYXQgdGhlIHBsb3QNCg0KYGBge3J9DQpiYXNlbWFwID0gbGVhZmxldChVU0FfZ3JvdXBfam9pbmVkX2N1dCkgJT4lIGFkZFRpbGVzKCkNCg0KYmFzZW1hcCAlPiUgbGVhZmxldC5taW5pY2hhcnRzOjphZGRGbG93cyhjb3VudHJpZXMkbG9uZ2l0dWRlW2NvdW50cmllcyRDb3VudHJ5ID09ICJVbml0ZWQgU3RhdGVzIl0sIGNvdW50cmllcyRsYXRpdHVkZVtjb3VudHJpZXMkQ291bnRyeSA9PSAiVW5pdGVkIFN0YXRlcyJdLFVTQV9ncm91cF9qb2luZWRfY3V0JGxvbmdpdHVkZSwgVVNBX2dyb3VwX2pvaW5lZF9jdXQkbGF0aXR1ZGUsDQogICAgZmxvdyA9IFVTQV9ncm91cF9qb2luZWRfY3V0JFRvdGFsVmFsdWUsDQogICAgdGltZSA9IFVTQV9ncm91cF9qb2luZWRfY3V0JFllYXIpDQpgYGANCg0K